import { EMediaType } from './constant';
import { handleError } from './error';
import to from 'await-to-js';

export let globalMediaStream: MediaStream;

export let globalDisplayMediaStream: MediaStream;

export interface IDeviceItem {
  id: string;
  kind: MediaDeviceKind;
  label: string;
}
// 获取本地媒体设备
export async function initInnerLocalDevice(constraints: MediaStreamConstraints = { video: true, audio: true }) {
  const localDevice = {
    audioIn: [] as IDeviceItem[],
    videoIn: [] as IDeviceItem[],
    audioOut: [] as IDeviceItem[],
  };

  // 不支持媒体设备获取api
  if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
    console.log('浏览器不支持获取媒体设备');
    return;
  }
  // getUserMedia获取媒体流
  const [getUserMediaError, stream] = await to(getMediaStream(constraints));
  if (getUserMediaError) {
    handleError(getUserMediaError);
  }

  // 关闭当前媒体流的所有媒体轨道
  stream?.getTracks().forEach((track) => {
    track.stop();
  });

  // 调用获取媒体设备的api获取devices数组
  const [enumerateDevicesError, devices] = await to(navigator.mediaDevices.enumerateDevices());
  if (enumerateDevicesError) {
    handleError(enumerateDevicesError);
  }
  // 遍历devices数组对设备进行分类
  devices?.forEach((device) => {
    const { deviceId: id, kind, label } = device;
    const deviceItem: IDeviceItem = {
      id,
      kind,
      label,
    };
    if (kind === EMediaType.AUDIOINPUT) {
      if (id && !localDevice.audioIn.find((device) => device.id === id)) {
        localDevice.audioIn.push(deviceItem);
      }
    } else if (kind === EMediaType.AUDIOOUTPUT) {
      if (id && !localDevice.audioOut.find((device) => device.id === id)) {
        localDevice.audioOut.push(deviceItem);
      }
    } else if (kind === EMediaType.VIDEOINPUT) {
      if (id && !localDevice.videoIn.find((device) => device.id === id)) {
        localDevice.videoIn.push(deviceItem);
      }
    }
  });
  return localDevice;
}

// 获取媒体流
export async function getMediaStream(constraints: MediaStreamConstraints = { video: true, audio: true }) {
  const [error, stream] = await to(navigator.mediaDevices.getUserMedia(constraints));
  if (error) {
    console.log(error);
    return;
  }
  if (globalMediaStream) {
    globalMediaStream.getTracks().forEach((track) => {
      track.stop();
    });
  }
  return (globalMediaStream = stream);
}

// 根据设备id获取指定的媒体轨道组成的媒体流
export async function getTargetIdStream(
  deviceId: { videoId?: string; audioId?: string },
  constraints?: MediaStreamConstraints,
) {
  const { videoId, audioId } = deviceId;
  if (globalMediaStream) {
    globalMediaStream.getTracks().forEach((track) => {
      track.stop();
    });
  }
  const [error, stream] = await to(
    getMediaStream({
      ...constraints,
      audio: { deviceId: audioId ? { exact: audioId } : undefined },
      video: {
        deviceId: videoId ? { exact: videoId } : undefined,
      },
    }),
  );
  if (error) return;
  return stream;
}

// 获取桌面媒体流
export async function getDisplayMediaStream(constraints: DisplayMediaStreamOptions = { video: true, audio: true }) {
  const [error, stream] = await to(navigator.mediaDevices.getDisplayMedia(constraints));
  if (error) {
    console.log(error);
    return;
  }
  if (globalDisplayMediaStream) {
    globalDisplayMediaStream.getTracks().forEach((track) => {
      track.stop();
    });
  }
  return (globalDisplayMediaStream = stream);
}
